package nc.wmsitf;

import com.alibaba.fastjson.JSONObject;
import nc.bs.framework.common.NCLocator;
import nc.itf.uap.IUAPQueryBS;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.vo.pub.BusinessException;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * WMS工具类
 */
public class WMSItfUtils {

    private static IUAPQueryBS bs = null;
    public static IUAPQueryBS getBs(){
        if(bs == null){
            bs = NCLocator.getInstance().lookup(IUAPQueryBS.class);
        }
        return bs;
    }

    public static String sendWMS(String path,String param) throws BusinessException {
        String token = getToken();
        Map<String, String> wmsConfig = getWMSConfig();
        String url = wmsConfig.get("url");
        url+=path;
        String result = sendByHttp(url,param,token);
        return result;
    }

    public static String getToken(){
        try {
            Map<String, String> wmsConfig = getWMSConfig();
            String url = wmsConfig.get("url")+"/logon/getToken";
            url+="?appid="+wmsConfig.get("appid");
            url+="&account="+wmsConfig.get("account");
            url+="&password="+wmsConfig.get("password");
            HttpGet httpGet = new HttpGet(url);
            httpClient = createSSLClientDefault();
            httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            if (httpEntity != null) {
                String jsObject = EntityUtils.toString(httpEntity, "UTF-8");
                return jsObject;
            } else {
                return null;
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            try {
                httpResponse.close();
                httpClient.close();
            } catch (IOException e) {
                throw new RuntimeException(e.getMessage());
            }
        }
    }

    public static Map<String,String> getWMSConfig() throws BusinessException {
        String sql = "SELECT d.CODE,d.NAME FROM bd_defdoc  d " +
                "LEFT JOIN bd_defdoclist def ON d.PK_DEFDOCLIST = def.PK_DEFDOCLIST  " +
                "WHERE def.code = 'wmsconfig' " +
                "AND d.dr = 0 AND def.dr = 0;";
        List<Map<String,Object>> list = (List<Map<String, Object>>) getBs().executeQuery(sql, new MapListProcessor());
        Map<String,String> returnMap = new HashMap<String,String>();
        if(list!=null&&list.size()>3){
            for(Map<String,Object> map : list){
                if("url".equals(map.get("code"))){
                    returnMap.put("url",map.get("name").toString());
                } else if ("account".equals(map.get("code"))) {
                    returnMap.put("account",map.get("name").toString());
                } else if ("appid".equals(map.get("code"))) {
                    returnMap.put("appid",map.get("name").toString());
                } else if ("password".equals(map.get("code"))) {
                    returnMap.put("password",map.get("name").toString());
                }
            }
        }else {
            throw new BusinessException("未配置wmsconfig环境参数！请检查自定义档案");
        }

        return returnMap;
    }


    public static String sendByHttp( String url,String json,String token) {
        try {
            JSONObject tokenObj = JSONObject.parseObject(token);
            String code = String.valueOf(tokenObj.get("code"));
            if(!"200".equals(code)){
                throw new BusinessException("token获取异常"+tokenObj.get("msg"));
            }
            JSONObject tokenData = tokenObj.getJSONObject("data");
            HttpPost httpPost = new HttpPost(url);
            StringEntity entity = new StringEntity(json, "UTF-8");
            httpPost.setEntity(entity);
            httpPost.addHeader("Content-Type", "application/json");
            httpPost.addHeader("Accept","application/json");
            httpPost.addHeader("Accept-Encoding", "identity");
            httpPost.addHeader("appid", tokenData.getString("appid"));
            httpPost.addHeader("token", tokenData.getString("token"));
            httpClient = createSSLClientDefault();
            httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            if (httpEntity != null) {
                String jsObject = EntityUtils.toString(httpEntity, "UTF-8");
                return jsObject;
            } else {
                return null;
            }
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        } finally {
            try {
                httpResponse.close();
                httpClient.close();
            } catch (IOException e) {
                throw new RuntimeException(e.getMessage());
            }
        }
    }

    static CloseableHttpClient httpClient;
    static CloseableHttpResponse httpResponse;

    public static CloseableHttpClient createSSLClientDefault() {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                // 信任所有
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();
            HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();

    }
}
